package com.cloudfun.campusshare.service.impl;

import cn.hutool.core.util.StrUtil;
import com.cloudfun.campusshare.common.constant.Code;
import com.cloudfun.campusshare.common.constant.OrderStatus;
import com.cloudfun.campusshare.common.constant.PayPlatform;
import com.cloudfun.campusshare.common.constant.RefundReview;
import com.cloudfun.campusshare.common.exception.BusinessException;
import com.cloudfun.campusshare.common.model.dto.RefundSettlementDto;
import com.cloudfun.campusshare.common.model.dto.ReplenishStatusCountDTO;
import com.cloudfun.campusshare.common.model.vo.OrderRefundAuditVo;
import com.cloudfun.campusshare.common.security.AuthenticationHolder;
import com.cloudfun.campusshare.entity.DeviceEntity;
import com.cloudfun.campusshare.entity.OrderEntity;
import com.cloudfun.campusshare.entity.OrderRefundEntity;
import com.cloudfun.campusshare.repo.OrderEntityRepo;
import com.cloudfun.campusshare.repo.OrderRefundEntityRepo;
import com.cloudfun.campusshare.repo.sql.SqlOrderRefund;
import com.cloudfun.campusshare.service.OrderRefundService;
import com.cloudfun.campusshare.service.PayService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;

@Service
public class OrderRefundServiceImpl implements OrderRefundService {

    @Autowired
    private OrderRefundEntityRepo orderRefundEntityRepo;
    @Autowired
    private OrderEntityRepo orderEntityRepo;

    @Autowired
    @Qualifier("kjtPayServiceImpl")
    private PayService payService;


    @Override
    public Page<OrderRefundEntity> page(Pageable pageable, String orderNo, RefundReview refundReview) {
        Specification<OrderRefundEntity> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> predicateList = new ArrayList<>();
            if (AuthenticationHolder.isCustomer()) {
                predicateList.add(criteriaBuilder.equal(root.get("customerId"), AuthenticationHolder.getUserId()));
            } else if (!AuthenticationHolder.isAdmin()) {
                predicateList.add(criteriaBuilder.equal(root.get("merchantId"), AuthenticationHolder.getUserId()));
            }
            if (StringUtils.isNotBlank(orderNo)) {
                predicateList.add(criteriaBuilder.equal(root.get("orderNo"), orderNo));
            }
            if (null != refundReview) {
                predicateList.add(criteriaBuilder.equal(root.get("refundReview"), refundReview));
            }
            Predicate[] predicates = new Predicate[predicateList.size()];
            predicateList.toArray(predicates);
            return criteriaBuilder.and(predicates);
        };
        pageable = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), Sort.by(Sort.Direction.DESC, "createTime"));
        return orderRefundEntityRepo.findAll(spec, pageable);
    }

    @Override
    public OrderRefundEntity get(Integer id) {

        return orderRefundEntityRepo.findById(id).get();
    }

    @Override
    public OrderRefundEntity audit(OrderRefundAuditVo auditVo) {
        OrderRefundEntity entity = orderRefundEntityRepo.findByOrderRefundNo(auditVo.getOrderRefundNo());
        OrderEntity orderEntity;
        if (entity == null) {
            throw new BusinessException(Code.ERROR, "退款订单不存在");
        } else if (entity.getOrderStatus() == OrderStatus.REFUND) {
            throw new BusinessException(Code.ERROR, "该订单已退款不能重复退款");
        } else if ((orderEntity = orderEntityRepo.findByOrderNo(entity.getOrderNo())) == null) {
            throw new BusinessException(Code.ERROR, "原订单号错误");
        } else if (entity.getRefundReview() != RefundReview.PENDING_REVIEW || entity.getRefundReview() != RefundReview.REFUNDING) {
            throw new BusinessException(Code.ERROR, "禁止重复审核");
        } else if (auditVo.getRefundReview() == RefundReview.FAIL) {
            entity.setRefundReview(auditVo.getRefundReview());
            entity.setRemark(auditVo.getRemark());
            orderRefundEntityRepo.save(entity);
            return entity;
        } else if (entity.getOrderStatus() == OrderStatus.ALREADY_COMPLETE &&
                entity.getPayPlatform() == PayPlatform.KJT_PAT &&
                auditVo.getRefundReview() == RefundReview.SUCCESS) {
            entity.setRefundReview(RefundReview.REFUNDING);
            payService.refund(entity);
            orderRefundEntityRepo.save(entity);
            return entity;
        } else if (auditVo.getRefundReview() == RefundReview.SUCCESS) {
            throw new BusinessException(Code.ERROR, String.format("%s%s", entity.getPayPlatform().getName(), "订单不支持退款"));
        } else {
            throw new BusinessException(Code.ERROR, "该订单不支持退款");
        }
    }

    @Override
    public List<RefundSettlementDto> refundSettlementStatistics(String data) {
        String sql = StrUtil.format(SqlOrderRefund.REFUND_SETTLEMENT_STATISTICS,data);
        return orderRefundEntityRepo.findNativeNamedQuery(sql, new Object[]{}, RefundSettlementDto.class);
    }
}
